package com.yilin.tms.core.commons.utils;

import com.google.gson.reflect.TypeToken;
import com.yilin.commons.encrypt.EncryptUtils;
import com.yilin.commons.util.DateTimeUtil;
import com.yilin.commons.util.JsonUtil;
import com.yilin.tms.core.application.AppUtil;
import com.yilin.tms.core.commons.constant.HttpConstant;
import com.yilin.tms.core.components.redis.RedisClient;
import com.yilin.tms.core.components.redis.RedisKeys;
import com.yilin.tms.core.entity.user.account.Account;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserUtil {


    //---------------------------------------------普通登录区-------------------------------------------------------

    //保存登录用户
    public static void saveLoginUser(Account account) {
        if (account.getToken()!=null) removeLoginUser(account.getToken());
        account.setToken(EncryptUtils.getToken());
        String objectToJson = JsonUtil.objectToJson(account);
        RedisClient.getInstance().hset(RedisKeys.ACCOUNT_LOGIN_KEY, account.getToken(),objectToJson);
    }

    //移除登录
    public static void removeLoginUser(String token) {
        if (token==null) return;
        RedisClient.getInstance().hdel(RedisKeys.ACCOUNT_LOGIN_KEY,token);
        RedisClient.getInstance().hdel(RedisKeys.ACCOUNT_API_KEY,token);
        RedisClient.getInstance().hdel(RedisKeys.ACCOUNT_ACCESS_KEY,token);
        RedisClient.getInstance().hdel(RedisKeys.ACCOUNT_SAFE_KEY,token);
    }

    //更新登录用户
    public static void updateLoginUser(Account account) {
        if (account == null || account.getToken() == null) return;
        if (RedisClient.getInstance().hget(RedisKeys.ACCOUNT_LOGIN_KEY,account.getToken())==null) return;
        String objectToJson = JsonUtil.objectToJson(account);
        RedisClient.getInstance().hset(RedisKeys.ACCOUNT_LOGIN_KEY,account.getToken(),objectToJson);
    }

    //获取请求登录用户
    public static Account getLoginUser(HttpServletRequest request) {
        String token = request.getHeader(HttpConstant.TOKEN);
        return getLoginUser(token);
    }

    //获取TOKEN登录用户
    public static Account getLoginUser(String token) {
        if (token==null) return null;
        String json = RedisClient.getInstance().hget(RedisKeys.ACCOUNT_LOGIN_KEY,token);
        if (json==null) return null;
        return JsonUtil.jsonToObject(json,new TypeToken<Account>(){});
    }


    //---------------------------------------------权限区-------------------------------------------------------

    //保存登录权限地址列表
    public static void saveGrantApiUrlList(String token, List<String> apiCodeList) {
        Account loginUser = getLoginUser(token);
        if (loginUser != null){
            RedisClient.getInstance().hset(RedisKeys.ACCOUNT_API_KEY, token, String.join(",",apiCodeList));
        }
    }

    //权限
    public static boolean checkGrantApi(String token,String code) {
        Account loginUser = getLoginUser(token);
        if (loginUser != null){
            String apiCodes = RedisClient.getInstance().hget(RedisKeys.ACCOUNT_API_KEY, token);
            return apiCodes.contains(code);
        }
        return false;
    }

    //---------------------------------------------访问刷新区-------------------------------------------------------

    //更新最新TOKEN访问时间
    public static void updateTokenAccessTime(String token) {
        if (token == null) return ;
        RedisClient.getInstance().hset(RedisKeys.ACCOUNT_ACCESS_KEY, token, DateTimeUtil.getTimeMillis());
    }

    //获取所有的TOKEN时间
    public static Map<String,Long> getAllTokenAccessTime() {
        Map<Object, Object> map = RedisClient.getInstance().hEntries(RedisKeys.ACCOUNT_ACCESS_KEY);
        Map<String,Long> accessMap = new HashMap<>();
        for (Object key : map.keySet()){
            if (map.get(key) == null) continue;
            long aLong = Long.parseLong(map.get(key).toString());
            accessMap.put(key.toString(),aLong);
        }
        return accessMap;
    }

    //---------------------------------------------安全密码区-------------------------------------------------------

    //生成安全密码验证识别码
    public static String generatePassCode(Account loginUser) {
        String uuid = AppUtil.getUUID().substring(0,32) + new Date().getTime();
        RedisClient.getInstance().hset(RedisKeys.ACCOUNT_SAFE_KEY,loginUser.getToken(), uuid);
        return uuid;
    }

    //验证识别码
    public static Boolean verifyPassCode(Account loginUser,String passCode){
        try {
            if (passCode == null) return false;
            String localPassCode = RedisClient.getInstance().hget(RedisKeys.ACCOUNT_SAFE_KEY,loginUser.getToken());
            if (!localPassCode.equals(passCode)) return false;
            String time = localPassCode.substring(32);
            Date date = new Date(Long.parseLong(time));
            int secondBetween = DateTimeUtil.secondBetween(date,new Date());
            if (secondBetween  >  3 * 60 ) {
                removePassCode(loginUser);
                return false;
            }
            return true;
        }catch (Exception e){
            return false;
        }
    }

    //移除密码识别码
    private static void removePassCode(Account loginUser) {
        RedisClient.getInstance().hdel(RedisKeys.ACCOUNT_SAFE_KEY,loginUser.getToken());
    }



}
